#coding=utf-8
'''
Created on 2017-04-26

@author: sandy
'''

import time
from twisted.internet import task
import logging
        
class LoginFailCtx(object):
    
    def __init__(self):
        self.failtimes = 0
        self.time = time.time()
        
class WebOrderOpCtx(object):
    
    def __init__(self):
        self.count = 0
        self.time = time.time()

class TimeCheck(object):
    
    def __init__(self):
        self.regipmap = {}
        self.loginfailmap = {}
        self.weborderop = {}
        self.checksessionmap = {}
        self.tick = None
    
    def start(self):
        l = task.LoopingCall(self.onTimer)
        l.start(2, False)
        self.tick = l
    
    def stop(self):
        #self.tick.stop()
        pass
    
    def onTimer(self):
        self.doTask()
        
    def doTask(self):
        now = time.time()
        self.checkLoginFail(now)
        self.checkWebOrder(now)
        self.checkRegisterIp(now)
        self.checkSessionMap(now)
    

    
    ###########################################################
    def addRegisterIp(self, ip):
        self.regipmap[ip] = time.time()
        
    def checkRegisterIp(self, now):
        removelist = []
        for k, v in self.regipmap.iteritems():
            if now-v>5:
                removelist.append(k)
        for k in removelist:
            self.regipmap.pop(k)
    
    def canDoRegisterIp(self, ip):
        lasttime = self.regipmap.get(ip)
        if lasttime==None:
            return True
        return False
    
    ###########################################################
    def addLoginFail(self, account):
        ctx = self.loginfailmap.get(account)
        if not ctx:
            ctx = LoginFailCtx()
            ctx.failtimes = 1
            self.loginfailmap[account] = ctx
        else:
            ctx.failtimes += 1
        
    def canLogin(self, account):
        ctx = self.loginfailmap.get(account)
        if not ctx:
            return True
        return ctx.failtimes<3
    
    def checkLoginFail(self, now):
        removelist = []
        for account,ctx in self.loginfailmap.iteritems():
            if now-ctx.time>10:
                removelist.append(account)
        for account in removelist:
            self.loginfailmap.pop(account) 
            
    #############################################################
    def addWebOrderOp(self, ip):
        ctx = self.weborderop.get(ip)
        if ctx==None:
            ctx = WebOrderOpCtx()
            ctx.count = 1
            self.weborderop[ip] = ctx
        else:
            ctx.count += 1
    
    def canDoWebOrderOp(self, ip):
        ctx = self.weborderop.get(ip)
        if ctx==None:
            return True
        return ctx.count<5
    
    def checkWebOrder(self, now):
        removelist = []
        for ip, ctx in self.weborderop.iteritems():
            if now-ctx.time>10:
                removelist.append(ip)
        for ip in removelist:
            self.weborderop.pop(ip)
    #########################################################
    def canCheckSession(self, uid):
        ctx = self.checksessionmap.get(uid)
        if not ctx:
            self.checksessionmap[uid] = [time.time()]
            return True
        now = time.time()
        if now-ctx[0]>2.0:
            ctx[0] = now
            return True
        return False
    
    def checkSessionMap(self, now):
        removelist = []
        for uid, ctx in self.checksessionmap.iteritems():
            if now-ctx[0]>120:
                removelist.append(uid)
        for uid in removelist:
            self.checksessionmap.pop(uid)

instance = TimeCheck()

if __name__ == '__main__':
    pass